package top.mybatisx.sql.core.sql;

import top.mybatisx.sql.core.sql.base.BaseSql;
import top.mybatisx.sql.core.sql.base.CondEnum;
import top.mybatisx.sql.core.sql.brige.ConditionAndBy;
import top.mybatisx.sql.core.sql.brige.JoinConditionAndBy;
import top.mybatisx.sql.core.table.CondColumn;
import top.mybatisx.sql.core.table.QueryColumn;
import top.mybatisx.sql.core.table.TableDef;
import top.mybatisx.sql.core.toolkit.Assert;

import java.util.List;

/**
 * 比较条件
 */
public interface JoinCondition<T extends JoinConditionAndBy> extends BaseSql {

    // ********* 以下是构造 关系条件 *********
    default T and_() {
        return makeCondition_(CondEnum.and);
    }

    default T or_() {
        return makeCondition_(CondEnum.or);
    }

    default T boxL_() {
        return makeCondition_(CondEnum.boxL);
    }

    default T boxR_() {
        return makeCondition_(CondEnum.boxR);
    }

    // ********* 以下是构造 对比 条件 *********

    default T eq_(QueryColumn column, Object value) {
        return eq_(true, column, value);
    }

    default T eq_(boolean isCheck, QueryColumn column, Object value) {
        return makeCondition_(isCheck, column, CondEnum.eq, value);
    }

    default T gt_(QueryColumn column, Object value) {
        return gt_(true, column, value);
    }

    default T gt_(boolean isCheck, QueryColumn column, Object value) {
        return makeCondition_(isCheck, column, CondEnum.gt, value);
    }

    default T ge_(QueryColumn column, Object value) {
        return ge_(true, column, value);
    }

    default T ge_(boolean isCheck, QueryColumn column, Object value) {
        return makeCondition_(isCheck, column, CondEnum.ge, value);
    }

    default T lt_(QueryColumn column, Object value) {
        return lt_(true, column, value);
    }

    default T lt_(boolean isCheck, QueryColumn column, Object value) {
        return makeCondition_(isCheck, column, CondEnum.lt, value);
    }

    default T le_(QueryColumn column, Object value) {
        return le_(true, column, value);
    }

    default T le_(boolean isCheck, QueryColumn column, Object value) {
        return makeCondition_(isCheck, column, CondEnum.le, value);
    }

    default T in_(QueryColumn column, Object value) {
        return in_(true, column, value);
    }

    default T in_(boolean isCheck, QueryColumn column, Object value) {
        return makeCondition_(isCheck, column, CondEnum.in, value);
    }

    default T notIn_(QueryColumn column, Object value) {
        return notIn_(true, column, value);
    }

    default T notIn_(boolean isCheck, QueryColumn column, Object value) {
        return makeCondition_(isCheck, column, CondEnum.notIn, value);
    }

    default T isNull_(QueryColumn column) {
        return makeCondition_(true, column, CondEnum.isNull, null);
    }

    default T notNull_(QueryColumn column) {
        return makeCondition_(true, column, CondEnum.notNull, null);
    }

    default T likeL_(QueryColumn column, Object value) {
        return likeL_(true, column, value);
    }

    default T likeL_(boolean isCheck, QueryColumn column, Object value) {
        return makeCondition_(isCheck, column, CondEnum.likeL, value);
    }

    default T likeR_(QueryColumn column, Object value) {
        return likeR_(true, column, value);
    }

    default T likeR_(boolean isCheck, QueryColumn column, Object value) {
        return makeCondition_(isCheck, column, CondEnum.likeR, value);

    }

    default T like_(QueryColumn column, Object value) {
        return like_(true, column, value);
    }

    default T like_(boolean isCheck, QueryColumn column, Object value) {
        return makeCondition_(isCheck, column, CondEnum.like, value);

    }

    // ********* 以下是实际执行 *********

    // 创建 关系队列
    default T makeCondition_(CondEnum relationEnum) {
        // 构造 关系
        CondColumn condColumn = new CondColumn(relationEnum);
        // 加入到条件队列
        this.getCondList_().add(condColumn);
        return (T) this;
    }

    // 创建 查询队列
    default T makeCondition_(boolean isCheck, QueryColumn column, CondEnum condEnum, Object value) {
        // 构造 查询条件
        CondColumn condColumn = new CondColumn(isCheck, column, condEnum, value);
        // 加入到条件队列
        this.getCondList_().add(condColumn);
        return (T) this;
    }

    // 获取 查询条件
    default List<CondColumn> getCondList_() {
        // 1. where ; 2 having
        if (isWhere.flag == 1) {
            return whereList;
        } else if (isWhere.flag == 2) {
            return havingList;
        }
        // 3. 剩下的, 生成的 条件全部加到 joinList
        Assert.notEmpty(joinList, "on 条件前,先写 join 相关函数");
        TableDef joinTable = joinList.get(joinList.size() - 1);
        return joinTable.getJoinConditionList();
    }

}
